#include <stdio.h>
#include "can.h"
#include "candemo.h"
#include "bsp_log.h"
#define MODE_NAME "CAN"
#define CAN_LOG_INFO(fmt, ...) BSP_LOG(LOG_INFO,"%s %s-%d "fmt,MODE_NAME,__FUNCTION__,__LINE__, ##__VA_ARGS__)
#define CAN_LOG_DEBUG(fmt, ...) BSP_LOG(LOG_DEBUG, "%s %s-%d "fmt,MODE_NAME,__FUNCTION__, __LINE__,##__VA_ARGS__)
#define CAN_LOG_ERROR(fmt, ...) BSP_LOG(LOG_ERROR, "%s %s-%d "fmt,MODE_NAME,__FUNCTION__, __LINE__,##__VA_ARGS__)

/**
 * @brief  配置并启动 CAN（允许接收所有 ID）
 */
void CAN_Config(void)
{
    CAN_FilterTypeDef filter;

    /* 选择滤波器组编号（0~13 可用，F1 系列有 14 个滤波器组） */
    filter.FilterBank = 0;

    /* 滤波器模式：
       CAN_FILTERMODE_IDMASK  = 掩码模式（允许通过的 ID 由 Mask 决定）
       CAN_FILTERMODE_IDLIST  = 列表模式（只允许特定 ID）
       这里用掩码模式，并配合 0x0000 掩码来放行所有 ID
    */
    filter.FilterMode = CAN_FILTERMODE_IDMASK;

    /* 滤波器位宽：
       CAN_FILTERSCALE_32BIT = 使用单个 32 位宽滤波器
       CAN_FILTERSCALE_16BIT = 使用两个 16 位宽滤波器
       这里用 32 位模式
    */
    filter.FilterScale = CAN_FILTERSCALE_32BIT;

    /* 设置滤波器的 ID 和 Mask：
       ID = 0x0000, Mask = 0x0000
       表示不过滤任何 ID（所有 ID 都能通过）
       这里 High/Low 是按位存储 CAN ID 的寄存器高 16 位和低 16 位
    */
    filter.FilterIdHigh = 0x0000;
    filter.FilterIdLow = 0x0000;
    filter.FilterMaskIdHigh = 0x0000;
    filter.FilterMaskIdLow = 0x0000;

    /* 将滤波器分配给 FIFO0（接收缓冲区 0） */
    filter.FilterFIFOAssignment = CAN_RX_FIFO0;

    /* 启用该滤波器 */
    filter.FilterActivation = ENABLE;

    /* 从第几个滤波器开始分配给从机 CAN（仅双 CAN 芯片使用）
       STM32F103 只有一个 CAN，这个值一般设为 14（默认）
    */
    filter.SlaveStartFilterBank = 14;

    /* 配置滤波器 */
    HAL_CAN_ConfigFilter(&hcan, &filter);

    /* 启动 CAN 外设 */
    HAL_CAN_Start(&hcan);
}

void CAN_Send_Test(void)
{
    CAN_TxHeaderTypeDef txHeader;
    uint8_t txData[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
    uint32_t txMailbox;

    txHeader.StdId = 0x123;
    txHeader.IDE = CAN_ID_STD;
    txHeader.RTR = CAN_RTR_DATA;
    txHeader.DLC = 8;
    txHeader.TransmitGlobalTime = DISABLE;

    if (HAL_CAN_AddTxMessage(&hcan, &txHeader, txData, &txMailbox) != HAL_OK)
    {
        CAN_LOG_ERROR("CAN Send Error!\r\n");
    }
    else
    {
        CAN_LOG_INFO("CAN message Send SCUUESS!\r\n");
		CAN_LOG_INFO("Send data:");
		for(int i = 0; i < 8; i ++)
		{
			printf("%02x",txData[i]);
		}
		printf("\r\n");
    }
}

void CAN_Receive_Test(void)
{
    CAN_RxHeaderTypeDef rxHeader;
    uint8_t rxData[8];

    // 查询 FIFO0 是否有消息
    if (HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) > 0)
    {
        if (HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &rxHeader, rxData) == HAL_OK)
        {
            CAN_LOG_INFO("Received CAN ID: 0x%X,\r\n", rxHeader.StdId);
			CAN_LOG_INFO("Received data:");
            for (int i = 0; i < rxHeader.DLC; i++)
            {
                printf("%02X", rxData[i]);
            }
            printf("\r\n");
        }
    }
}